package com.intel.factorytest.activity;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set; 
import java.util.Timer;
import java.util.TimerTask;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.intel.factorytest.R;
import com.intel.factorytest.application.MATApplication;
import com.intel.factorytest.cfparser.ConfigFileParseUtil;
import com.intel.factorytest.cfparser.concrete.AConfigFileParser;
import com.intel.factorytest.cfparser.concrete.PropertiesConfParser;
import com.intel.factorytest.log.LogWriter;
import com.intel.factorytest.util.LogUtils;

public class WifiTest extends BaseActivity {
    private static final String TAG = "WifiTest";
    private static final int MAX_COUNT_DEV_DISPLAY = 5;
    // private static final int MAX_COUNT_DEV_DISPLAY = 3;
    private static final String TAG_WIFI_BT = "WifiAndBlutooth";
    private static final String TAG_WIFI = "WIFI";
    private static final String TAG_BT = "Bluetooth";
    private static final String TAG_WIFI_BT_zh = "WIFI和蓝牙测试";
    private static final String TAG_WIFI_zh = "WIFI测试";
    private static final String TAG_BT_zh = "蓝牙测试";
    private static final int BT_NODEFINE_BASE_LINE = 70;
    private static final int WIFI_NODEFINE_BASE_LINE = 70;
    private static final Map<String, String> nameMapping_language = new HashMap<String, String>();
    static {
        nameMapping_language.put(TAG_WIFI_BT, TAG_WIFI_BT_zh);
        nameMapping_language.put(TAG_WIFI, TAG_WIFI_zh);
        nameMapping_language.put(TAG_BT, TAG_BT_zh);
    }
    
    // Handler Message
    private static final int MSG_CHECK_RESULT = 1;

    // Timer
    private Timer mTimer_CheckResult = null;

    // properties
    private Properties properties;

    // test result
    private boolean resultWifiOK = false;

    private boolean mCanScanWIFI = false;

    // properties key
    private static final String KEY_WIFI_SSID = "WIFI_SSID";
    private static final String KEY_WIFI_RSSI = "WIFI_RSSI";
    private static final String KEY_WIFI_RSSI_ERROR_LIMITATION = "WIFI_RSSI_ERROR_LIMITATION";

    // properties value
    private String valueWifiSsid; // properties.get(KEY_WIFI_SSID);
    private String valueWifiRssi; // properties.get(KEY_WIFI_RSSI);
    private int valueWifiRssiErrorLimitation = 10; // default value (dbm)
    private String[] ssidsWifi;
    private String[] rssisWifi;



    // #####  WIFI  #####
    private WifiManager mWifiManager = null;
    private static final int SET_WIFI_STATUS = 1;
    private static final int RESTORE_WIFI_STATUS = 2;
    private Timer mTimer_Wifi;
    private IntentFilter mFilter_Wifi = null;
    private Scanner mScanner_Wifi;
    private BroadcastReceiver mReceiver_Wifi;
    private TextView wifiLabelText = null;
    private TextView wifiInfosTv = null;
    private boolean mWifiEnable = false;
    Handler mHandler_Wifi = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == SET_WIFI_STATUS) {
                if (!mWifiManager.isWifiEnabled()) {
                    mWifiManager.setWifiEnabled(true);
                }
            } else if (msg.what == RESTORE_WIFI_STATUS) {
                LogUtils.logi("handleMessage mWifiEnable = " + mWifiEnable + ",mWifiManager.isWifiEnabled() = " + mWifiManager.isWifiEnabled());
                if (mWifiManager.isWifiEnabled() && !mWifiEnable) {
                    mWifiManager.setWifiEnabled(false);
                }
            } else {
            }
        }
    };

    private boolean isCheckedWIFI = false;
    boolean isExistAll_wifi = false;
//    boolean isSsidBeyondLimit_wifi = false;
    boolean isWIFISsidTestOK = false;
    private boolean isSearched5Gwifi = false;
    private boolean isWifiScanned = false;

    protected void onCreate(android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // load properties configuration file
        
        properties = ((PropertiesConfParser) ConfigFileParseUtil.getConfParserConcrete(this, AConfigFileParser.EXTENSION_PROPERTISE)).getProperties(isPcba);
        valueWifiSsid = properties.getProperty(KEY_WIFI_SSID);
        valueWifiRssi = properties.getProperty(KEY_WIFI_RSSI);
        valueWifiRssiErrorLimitation = Integer.parseInt(properties.getProperty(KEY_WIFI_RSSI_ERROR_LIMITATION));
        ssidsWifi = valueWifiSsid.split("\\;");
         rssisWifi = valueWifiRssi.split("\\;");
         Log.i(TAG, "onCreate valueWifiSsid = " + valueWifiSsid + ", valueWifiRssi = " + valueWifiRssi);
         Log.i(TAG, "onCreate ssidsWifi = " + ssidsWifi + ", rssisWifi = " + rssisWifi);
        setContentView(R.layout.wifi_test_layout);
        initView();

        mFilter_Wifi = new IntentFilter();
        mFilter_Wifi.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mFilter_Wifi.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mReceiver_Wifi = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!isCheckedWIFI) {
                    handleWifiEvent(context, intent);
                }
            }
        };

        mScanner_Wifi = new Scanner();
        mWifiManager = (WifiManager) this
                .getSystemService(Context.WIFI_SERVICE);
        mWifiEnable = mWifiManager.isWifiEnabled();
        LogUtils.logi("onCreate mWifiEnable = " + mWifiEnable);

    }

    protected void initView() {
        wifiLabelText = (TextView) findViewById(R.id.wifiTextView);
        wifiLabelText.setText(this.getString(R.string.WIFI_TITLE));
        
        wifiInfosTv = (TextView) findViewById(R.id.wifiInfos);
        mSucBtn = (Button) findViewById(R.id.success_button);
        //if (isSystemTest)
        //{
        
            Log.i(TAG, "initView isSystemTest= " + isSystemTest);
            mSucBtn.setVisibility(View.INVISIBLE);
        //}
        
        mFailBtn = (Button) findViewById(R.id.fail_button);
        attachListener();
    }

    private void attachListener() {
        mSucBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                is_pass = true;
                finish();
            }
        });
        attachOnTouchListener(mSucBtn);

        mFailBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                is_pass = false;
                finish();
            }
        });
        attachOnTouchListener(mFailBtn);
        
    }

    private Handler mHandler_CheckResult = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            // update is_pass
            
            Log.i(TAG, "mHandler_CheckResult isWifiTestOK()= " + isWifiTestOK());
            if (isWifiTestOK()) {
                is_pass = true;
            } else {
                is_pass = false;
            }
            Log.i(TAG, "mHandler_CheckResult is_pass= " + is_pass);
            Log.i(TAG, "mHandler_CheckResult msg.what= " + msg.what);

            switch (msg.what) {
            case MSG_CHECK_RESULT:
                if (is_pass) {
                    mSucBtn.setVisibility(View.VISIBLE);
                    //finish();
                } else {
                    if (mCanScanWIFI && isSearched5Gwifi){
                        mSucBtn.setVisibility(View.VISIBLE);
                        is_pass = true;
                        //finish();
                    } else {
                        mSucBtn.setVisibility(View.INVISIBLE);
                        is_pass = false;
                    }
                    mFailBtn.setVisibility(View.VISIBLE);
                    mFailBtn.setEnabled(true);
                    //mFailBtn.setBackgroundColor(Color.WHITE);//remove by wagnsm
                }
                break;
            default:
                break;
            }

        }

    };

     private boolean checkWifiErrorResult(String ssid, int rssi) {

         rssi = Math.abs(rssi);
         
         boolean ssidExist = false;
         int compareRssi = 0;
         for (int i = 0; i < ssidsWifi.length; i++) {
            if (ssid.equals(ssidsWifi[i])) {
                compareRssi = Math.abs(Integer.parseInt(rssisWifi[i]));
                ssidExist = true;
            }
        }

         // 对于不在配置文件列表中的Wifi不做检查, 直接返回true.
         if (!ssidExist) {
             return true;
         }

//         return Math.abs(rssi - compareRssi) <= valueWifiRssiErrorLimitation;
         return Math.abs(compareRssi)>Math.abs(rssi)?true:false;    
     }
     
     private boolean checkAllWifiSsidExist(String[] ssids, List<ScanResult> scanResults) {
         // empty string
         if (ssidsWifi != null && ssidsWifi.length == 1 && ssidsWifi[0].trim().length() == 0) {
            return true;
        }

         for (String ssid : ssids) {
             boolean isExist = false;
            for (ScanResult scanResult : scanResults) {
                if (scanResult.SSID.equals(ssid)) {
                    isExist = true;
                }
            }
            if (!isExist) {
                return false;
            }
        }
         return true;
     }


     /**
      * 检查SSID and RSSI的数量是否一致
      * @return
      */
     private boolean checkWifiFormat() {
     
     Log.i(TAG, "checkWifiFormat valueWifiSsid= " + valueWifiSsid + ", valueWifiSsid.trim().length() = " + valueWifiSsid.trim().length() + ",valueWifiRssi = " + valueWifiRssi + ",valueWifiRssi.trim().length() = " + valueWifiRssi.trim().length());
         if (valueWifiSsid == null || valueWifiSsid.trim().length() == 0 
                 || valueWifiRssi == null || valueWifiRssi.trim().length() == 0) {
             return false;
         }
         
         Log.i(TAG, "checkWifiFormat ssidsWifi.length= " + ssidsWifi.length + ",rssisWifi.length = " + rssisWifi.length);
         if (ssidsWifi.length != rssisWifi.length) {
             return false;
         }
         return true;
     }


     private void startCheck() {
         
         mTimer_CheckResult = new Timer();
         TimerTask task = new TimerTask() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                if (isSystemTest) {
                    mHandler_CheckResult.sendEmptyMessage(MSG_CHECK_RESULT);
                }
            }
        };
        mTimer_CheckResult.schedule(task, 500, 500);

     }

    private void getWifiinfo() {
        mWifiManager.getConnectionInfo();
    }

    private void handleWifiEvent(Context context, Intent intent) {
        String action = intent.getAction();
        Log.i(TAG, "action = " + action);
        StringBuilder strBuilder = new StringBuilder();
        //System.out.println("tangjun handle wifi action = " + action);
        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                    WifiManager.WIFI_STATE_UNKNOWN));
            Log.i(TAG, "updateWifiState");
        } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
            List<ScanResult> results = mWifiManager.getScanResults();
             Log.i(TAG,"handle wifi : scanResult.length = " + results.size());
            
            if (results.size()!=0)
            {
                mCanScanWIFI=true;
            }
            
            scanedSsid.clear();

            if (!checkAllWifiSsidExist(ssidsWifi, results)) {
                isExistAll_wifi = false;
            } else {
                isExistAll_wifi = true;
            }

//            StringBuilder strBuilder = new StringBuilder("\n");
            int wifiCount = 0;
            for (ScanResult scanResult : results) {
                Log.i(TAG," handle wifi : name = " + scanResult.SSID);
                
                Log.i(TAG," handle wifi : ssidsWifi = " + ssidsWifi);
                for (int i = 0; i < ssidsWifi.length; i++) {
                    
                    Log.i(TAG," handle wifi : for ssidsWifi[i] = " + ssidsWifi[i] + ",isScaned(scanResult.SSID) = " + isScaned(scanResult.SSID));
                    if (scanResult.SSID.equals(ssidsWifi[i]) && !isScaned(scanResult.SSID)) {
                        scanedSsid.add(scanResult.SSID);

                        wifiCount++;
                        strBuilder.append(getString(R.string.SSID) + scanResult.SSID + "\n" + getString(R.string.RSSI) + scanResult.level + "dbm");
                        
                        if (isSystemTest) {
                            boolean isPass = false;
                            
                            Log.i(TAG," handle wifi : checkWifiFormat() = " + checkWifiFormat());
                            if (checkWifiFormat()) {
                                isPass = checkWifiErrorResult(scanResult.SSID, scanResult.level);
                                 Log.i(TAG," handle wifi : isPass = " + isPass);
                                if (!isPass) {
                                    strBuilder.append(getString(R.string.RSSIFail));
                                    isWIFISsidTestOK = false;
                                } else {
                                    strBuilder.append(getString(R.string.RSSIPass));
                                    isWIFISsidTestOK = true;
                                }
                            }
                        }
                        strBuilder.append("\n");
                    }
                }
            }

            isSearched5Gwifi = false;
            for (ScanResult scanResult : results) {
                
                if (wifiCount >= MAX_COUNT_DEV_DISPLAY) {
                    break;
                }

                boolean ssidExist = false;
                for (int i = 0; i < ssidsWifi.length; i++) {
                    if (scanResult.SSID.equals(ssidsWifi[i])) {
                        ssidExist = true;
                        break;
                    }
                }
                if (!ssidExist && !isScaned(scanResult.SSID)) {
                    strBuilder.append(getString(R.string.SSID) + scanResult.SSID + "\n" + getString(R.string.RSSI) + scanResult.level + "dbm");
                    Log.i(TAG," handle wifi : scanResult.level = " + scanResult.level);

                    if (CheckRSSIResult(WIFI_NODEFINE_BASE_LINE,scanResult.level)) 
                    {
                       strBuilder.append(getString(R.string.RSSIPass));                       
                       Log.i(TAG," handle wifi : strBuilder = " + strBuilder);
                       isWIFISsidTestOK = true;
                    }
                    
                    strBuilder.append("\n");
                    scanedSsid.add(scanResult.SSID);
                    wifiCount++;
                }

                if (scanResult.SSID != null && (scanResult.SSID.contains("5G") || scanResult.SSID.contains("5g"))) {
                    isSearched5Gwifi = true;
                }
            }

//            String tmpStr = this.getString(R.string.SERVICEMENU_OPEN_TXT)
//                    + "\n"
//                    + this.getString(R.string.SERVICEMENU_SCAN_RESULT_TXT)
//                    + results.size();
//            is_pass = false;
//            if (results.size() > 0) {
//                is_pass = true;
//                tmpStr += "\n"
//                        + this.getString(R.string.SERVICEMENU_TEST_RESULT_TXT);
//            }
//            wifiInfosTv.setText(tmpStr);
            //wifiInfosTv.setText(strBuilder.toString());
            Log.i(TAG, "results.size() = " + results.size());
            Log.i(TAG, "isExistAll_wifi = " + isExistAll_wifi + ",isWIFISsidTestOK = " + isWIFISsidTestOK);
            if (isExistAll_wifi && isWIFISsidTestOK) {
                resultWifiOK = true;
            } else {
                resultWifiOK = false;
            }

             isWifiScanned = true;
        }

            // chenkang add for displaying wifi hardware & firmware info, etc.
            if (isWifiScanned) {
                final StringBuilder sb = new StringBuilder("");
                InputStreamReader input = null;

                Log.d(TAG, "before ProcessBuilder...");

                try {
                    java.lang.Process info_read = new ProcessBuilder("/system/bin/cat", "/sys/module/bcmdhd/parameters/info_string").start();
                    input = new InputStreamReader(info_read.getInputStream());

                    int num;
                    char[] buf = new char[128];
                    while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);

                    Log.d(TAG, "Get winfo info: " + sb.toString());

                } catch (IOException e) {
                    Log.e(TAG, "Error running cat", e);
                } finally {
                    if (input != null) try { input.close(); } catch (IOException e) {}
                }

                if (!"".equals(sb.toString())) {
                    strBuilder.append("\n");
                }
                strBuilder.append(sb);
            }
            wifiInfosTv.setText(strBuilder.toString());
            // chenkang add end

    }
    
    List<String> scanedSsid = new ArrayList<String>();
    private boolean isScaned(String ssid) {
        return scanedSsid.contains(ssid);
    }

    protected boolean CheckRSSIResult(int baseline, int actual) {        
         return Math.abs(baseline)>Math.abs(actual)?true:false;        
     }

    private void updateWifiState(int state) {
        switch (state) {
        case WifiManager.WIFI_STATE_ENABLED:
            wifiInfosTv.setText(this.getString(R.string.SERVICEMENU_OPEN_TXT));
            mScanner_Wifi.resume();
            return; // not break, to avoid the call to pause() below

        case WifiManager.WIFI_STATE_ENABLING:
            break;

        case WifiManager.WIFI_STATE_DISABLED:
            wifiInfosTv.setText(this.getString(R.string.SERVICEMENU_TEST_RESULT_FAIL_TXT));
            break;
        }

        mScanner_Wifi.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //registerReceiver(mReceiver_Wifi, mFilter_Wifi, "permission.CIT_ALLOW_BROADCAST", null);        
        registerReceiver(mReceiver_Wifi, mFilter_Wifi);
        mTimer_Wifi = new Timer();
        mTimer_Wifi.schedule(new TimerTask() {
            @Override
            public void run() {
                mHandler_Wifi.sendEmptyMessage(SET_WIFI_STATUS);
            }

        }, 1000);

        // check result
        startCheck();
        mItemTestFinish = true;//add by wangsm
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver_Wifi);
        mScanner_Wifi.pause();
        if (mTimer_CheckResult != null) {
            mTimer_CheckResult.cancel();
        }
    }

    @Override
    public void onDestroy() {
        restoreWIFIThread();
        super.onDestroy();
    }

    Runnable runnable = new Runnable() {

        public void run() {
            mHandler_Wifi.sendEmptyMessage(RESTORE_WIFI_STATUS);
        };
    };

    private void restoreWIFIThread() {
       new Thread(runnable).start();
    }

    private class Scanner extends Handler {
        private int mRetry = 0;

        void resume() {
            if (!hasMessages(0)) {
                sendEmptyMessage(0);
            }
        }

        void forceScan() {
            removeMessages(0);
            sendEmptyMessage(0);
        }

        void pause() {
            mRetry = 0;
            removeMessages(0);
        }

        @Override
        public void handleMessage(Message message) {
            if (mWifiManager.startScan()) {
                mRetry = 0;
            } else if (++mRetry >= 3) {
                mRetry = 0;
                return;
            }
            sendEmptyMessageDelayed(0, 10 * 1000);
        }
    }

    @Override
    public void finish() {
        isLogged = true;
        scanedSsid.clear();
        super.finish();
    }


    private boolean isWifiTestOK() {
        return resultWifiOK;
    }
}
